#include "alarmqueue.h"
#include "xml.h"
#include "network.h"
#include "common.h"
#include "onvifinit.h"
#include "groupxmlcommon.h"


typedef struct _PullAlarmInfo_T{
	char *msg;
	char ethname[32];
	int  socked;
	struct			listnode _list;
}PullAlarmInfo_T;

typedef struct _PullAlarmInfoManage_T{
	PullAlarmInfo_T info;
	struct			listnode _list;
	pthread_mutex_t 		mutex;	
}PullAlarmInfoManage_T;

static PullAlarmInfoManage_T *pullQueueHead;

static int GetPullMsgCnt()
{
	struct	listnode *node = NULL;
	int cnt = 0;
	
	pthread_mutex_lock(&(pullQueueHead->mutex));
	list_for_each(node, &(pullQueueHead->_list)){
		cnt++;
	}
	pthread_mutex_unlock(&(pullQueueHead->mutex));
	return cnt;
}

static int SendRequst(PullAlarmInfo_T *info)
{
	ClientReqObj_T obj;
	memset(&obj,0,sizeof(ClientReqObj_T));
	obj.msg = info->msg;
	obj.ethname = info->ethname;
	obj.msgType = ONVIF_REQMSGTYPE_REPULLMSG;
	int iret = OnvifSerParaOnvifMsg(&obj);
	DF_DEBUG("MSG = [%s]",obj.msg);
	DF_DEBUG("ethname = [%s]",obj.ethname);
	DF_DEBUG("msgType = [%d]",obj.msgType);
	DF_DEBUG("SendRequst = %d",iret);
	NetTcpSendMsg(info->socked,obj.buf,strlen(obj.buf));
	DF_DEBUG("socked = %d",info->socked);
	DF_DEBUG("msgbuf = [%s]",obj.buf);
	return KEY_TRUE;
}

int DealWithPullMsgQueue()
{
	int cnt = GetPullMsgCnt();
	int i = 0;
	struct	listnode *node = NULL;
	PullAlarmInfoManage_T	*obj = NULL;
	pthread_mutex_lock(&(pullQueueHead->mutex));
	list_for_each(node, &(pullQueueHead->_list)){
		obj = node_to_item(node,PullAlarmInfoManage_T,_list);
		pthread_mutex_lock(&(obj->mutex));
		onvif_list_remove(&(obj->_list));
		SendRequst(&(obj->info));
		DF_DEBUG("MSG = [%s]",obj->info.msg);
		DF_DEBUG("ethname = [%s]",obj->info.ethname);
		free(obj->info.msg);
		pthread_mutex_unlock(&(obj->mutex));
		free(obj);
		obj = NULL;
	}
	pthread_mutex_unlock(&(pullQueueHead->mutex));	
	return KEY_TRUE;
}



int AddPullMsgQueue(char *msg,char *ethname,int socked)
{
	PullAlarmInfoManage_T *obj = NULL; 
	obj = (PullAlarmInfoManage_T *)malloc(sizeof(PullAlarmInfoManage_T));	
	if(NULL == obj){
		return KEY_FALSE;
	}
	memset(obj,0,sizeof(PullAlarmInfoManage_T));
	obj->info.msg =(char *)malloc(DF_NET_MSGBUFLEN);
	if(NULL == obj->info.msg){
		free(obj);
		return KEY_FALSE;
	}
	memset(obj->info.msg,0,sizeof(DF_NET_MSGBUFLEN));
	memcpy(obj->info.msg,msg,strlen(msg));
	memcpy(obj->info.ethname,ethname,strlen(ethname));
	obj->info.socked = socked;
	//DF_DEBUG("MSG = [%s]",obj->info.msg);
	//DF_DEBUG("ethname = [%s]",obj->info.ethname);
	pthread_mutex_init(&(obj->mutex), NULL);	
	pthread_mutex_lock(&(pullQueueHead->mutex));
	onvif_list_add_tail(&(pullQueueHead->_list),&(obj->_list));
	pthread_mutex_unlock(&(pullQueueHead->mutex));
	pthread_mutex_destroy(&(obj->mutex));
	return KEY_TRUE;
}

int InitAlarmManagePullMsgQueue()
{
	pullQueueHead = NULL;
	pullQueueHead = (PullAlarmInfoManage_T *)malloc(sizeof(PullAlarmInfoManage_T));
	if(NULL == pullQueueHead){
		return KEY_FALSE;
	}
	memset(pullQueueHead,0,sizeof(PullAlarmInfoManage_T));
	pthread_mutex_init(&(pullQueueHead->mutex), NULL);
	pthread_mutex_lock(&(pullQueueHead->mutex));
	onvif_list_init(&(pullQueueHead->_list));
	pthread_mutex_unlock(&(pullQueueHead->mutex));
	pthread_mutex_destroy(&(pullQueueHead->mutex));
	return KEY_TRUE;
}

int DealWithPushMsg(PushMsg_T *obj)
{
	char host[128] = {0}, notifyXaddr[128] = {0}; 	
	Root_T *root = CreatRoot();
	char buff[1024 * 3] = {0};
	char readBuff[1024 * 20]= {0};
	char msgId[128];
	XmlElementObj_T *Envelope_0 = NULL;
	XmlElementObj_T *Header_1 = NULL;
	XmlElementObj_T *Body_2 = NULL;
	XmlElementObj_T *Notify_3 = NULL;
	XmlElementObj_T *NotificationMessage_4 = NULL;
	XmlElementObj_T *SubscriptionReference_5 = NULL;
	XmlElementObj_T *ProducerReference_6 = NULL;
	XmlElementObj_T *Message_7 = NULL;
	XmlElementObj_T *Message_8 = NULL;
	XmlElementObj_T *Source_9 = NULL;
	XmlElementObj_T *Data_10 = NULL;

 	Envelope_0 = CreateXmlElementObj(root,"s","Envelope",NULL,NULL,NULL);
	Header_1 = CreateXmlElementObj(root,"s","Header",NULL,NULL,Envelope_0);
	Body_2 = CreateXmlElementObj(root,"s","Body",NULL,NULL,Envelope_0);
	
	CreateXmlElementObj(root,"wsa5","MessageID",NULL,GetMsgUuid(msgId, sizeof(msgId)),Header_1);
	//CreateXmlElementObj(root,"wsa5","To","SOAP-ENV:mustUnderstand=\"true\"",obj->notifyServer,Header_1);
	//CreateXmlElementObj(root,"wsa5","Action","SOAP-ENV:mustUnderstand=\"true\"","http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify",Header_1);
	CreateXmlElementObj(root,"wsa5","To","s:mustUnderstand=\"true\"",obj->notifyServer,Header_1);
	CreateXmlElementObj(root,"wsa5","Action","s:mustUnderstand=\"true\"","http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify",Header_1);
	Notify_3 = CreateXmlElementObj(root,"wsnt","Notify",NULL,NULL,Body_2);
	NotificationMessage_4 = CreateXmlElementObj(root,"wsnt","NotificationMessage",NULL,NULL,Notify_3);
	SubscriptionReference_5 = CreateXmlElementObj(root,"wsnt","SubscriptionReference",NULL,NULL,NotificationMessage_4);
	CreateXmlElementObj(root,"wsa5","Address",NULL,obj->address,SubscriptionReference_5);
	CreateXmlElementObj(root,"wsnt","Topic","Dialect=\"http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet\"","tns1:RuleEngine/CellMotionDetector/Motion",NotificationMessage_4);
	ProducerReference_6 = CreateXmlElementObj(root,"wsnt","ProducerReference",NULL,NULL,NotificationMessage_4);
	CreateXmlElementObj(root,"wsa5","Address",NULL,obj->eventService,ProducerReference_6);
	Message_7 = CreateXmlElementObj(root,"wsnt","Message",NULL,NULL,NotificationMessage_4);
	Message_8 = CreateXmlElementObj(root,"tt","Message","PropertyOperation=\"Initialized\" UtcTime=\"2018-09-07T14:32:51Z\"",NULL,Message_7);
	Source_9 = CreateXmlElementObj(root,"tt","Source",NULL,NULL,Message_8);
	CreateXmlElementObj(root,"tt","SimpleItem","Value=\"000\" Name=\"VideoSourceConfigurationToken\"",NULL,Source_9);
	CreateXmlElementObj(root,"tt","SimpleItem","Value=\"000\" Name=\"VideoAnalyticsConfigurationToken\"",NULL,Source_9);
	CreateXmlElementObj(root,"tt","SimpleItem","Value=\"000\" Name=\"Rule\"",NULL,Source_9);
	Data_10 = CreateXmlElementObj(root,"tt","Data",NULL,NULL,Message_8);
	CreateXmlElementObj(root,"tt","SimpleItem","Value=\"true\" Name=\"IsMotion\"",NULL,Data_10);
	NamespaceRecord(root,"tns1");
	OnvifCliWriteNameSpace(Envelope_0);
	XmlElemnt(Envelope_0);
	
	
	memset(host,0,sizeof(host));
	sscanf(obj->notifyServer,"http://%[^/]%s", host, notifyXaddr);
	//OnvifCliGroupPostHead(obj->pushAlarmIp,obj->notifyServer,root->buff,buff);
	
	OnvifCliGroupPostHead(host, notifyXaddr, root->buff, buff);
	if(KEY_FALSE != NetTcpGetMsg(obj->pushAlarmIp,obj->pushAlarmPort,buff,strlen(buff),readBuff,sizeof(readBuff),500,NULL)){
		DF_DEBUG("readbuf = [%s]",readBuff);
	}
	
	DelAllXmlElementObj(Envelope_0);
	DelRoot(root);
	return KEY_TRUE;
}


